package com.woniuxy.woniufp.bank.service.impl;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniuxy.woniufp.bank.entity.TradeLog;
import com.woniuxy.woniufp.bank.mapper.TradeLogMapper;
import com.woniuxy.woniufp.bank.service.ITradeLogService;
import com.woniuxy.woniufp.common.model.constant.UserConstant;
import com.woniuxy.woniufp.common.model.dto.bank.BankCardAddDTO;
import com.woniuxy.woniufp.common.model.dto.bank.SignatureDTO;
import com.woniuxy.woniufp.common.model.exceptions.BusinessException;
import com.woniuxy.woniufp.common.model.result.Result;
import com.woniuxy.woniufp.common.model.result.enums.impl.BusinessCode;
import com.woniuxy.woniufp.common.model.utils.EncryptUtil;
import com.woniuxy.woniufp.common.model.vo.trade.BorrowSyncRecordVo;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

@Service
@Slf4j
public class TradeLogServiceImpl implements ITradeLogService {
    @Autowired
    TradeLogMapper tradeLogMapper ;

    @Autowired
    RestTemplate restTemplate ;

    @SneakyThrows  //把编译时异常转变成 运行时异常
    @Override
   @Transactional
    public SignatureDTO proxyBindCardLog(BankCardAddDTO bankCardAddDTO) {
        //1.插入 操作记录的明细 trade_log
        TradeLog tradeLog = new TradeLog();
        tradeLog.setReqCode(bankCardAddDTO.getReqCode());
        tradeLog.setReqType(UserConstant.REQUEST_USER);  //USER_BIND_CARD
        tradeLog.setObjectId(bankCardAddDTO.getUserId());
        tradeLog.setCreateDate(new Date());
        tradeLog.setSynchronizeStatus(0);
        tradeLog.setConfirmDate(new Date());
        tradeLog.setResponseData(new ObjectMapper().writeValueAsString(bankCardAddDTO));

        tradeLogMapper.insert(tradeLog);

        //int i = 10 / 0 ;  //报错
        //2. 封装返回对象
        SignatureDTO signatureDTO = new SignatureDTO();
        signatureDTO.setReqCode(bankCardAddDTO.getReqCode());
        signatureDTO.setPlatformNo("蜗牛学院");
        signatureDTO.setReqData(new ObjectMapper().writeValueAsString(bankCardAddDTO));
        signatureDTO.setBankUrl("http://localhost:5600/bank/user");
        return signatureDTO;
    }

    @Override
    public void modifyRequestStatus(String reqCode, int i) {
        tradeLogMapper.updateRequestStatusByReqCode(reqCode,i);
    }

    /**
     * 为什么把Java对象进行序列化 ？
     * 因为Java对象只能在java的虚拟机中识别执行，如果我们想把Java对象保存到文件 或者在网络中传输。
     * 那么不能直接使用Java对象 ，所以我们必须把Java对象序列化，序列化成文件能识别的数据 ，或者在网略中
     * 能传递的数据，（流或者 字符串）
     * 也就是说序列化有两种方式 ：
     * 1. 序列化成流  java的对象所在的类 实现 Serializable接口
     * 2. 把对象序列化成JSON字符窜
     */

    @SneakyThrows
    @Override
    public void syncBorrowRecord(BorrowSyncRecordVo borrowSyncRecordVo) {
        // 1. 保存交易记录
        //1.插入 操作记录的明细 trade_log
        TradeLog tradeLog = new TradeLog();
        tradeLog.setReqCode(borrowSyncRecordVo.getReqCode());
        tradeLog.setReqType(UserConstant.BORROW_RECORD_SYNC);  //BORROW_RECORD_SYNC
        tradeLog.setObjectId(borrowSyncRecordVo.getId());
        tradeLog.setCreateDate(new Date());
        tradeLog.setSynchronizeStatus(0);
        tradeLog.setResponseData(new ObjectMapper().writeValueAsString(borrowSyncRecordVo));
        //保存
        tradeLogMapper.insert(tradeLog);

        //2.发起远程调用  访问 银行托管中心
        // url ：http://localhost:5600/service?serviceName=SYNC_BORROW_RECORD&reqData=xxx
        /*
          encode  ---> base64
        String decodeUrlData = EncryptUtil.decodeURL(reqData); 1 .encode 解码
		String decodeReqData = EncryptUtil.decodeUTF8StringBase64(decodeUrlData); //base64解码

        传递数据时 ，需要编码 ：
        base64 ---> encode
        为什么需要编码传递
         */
        //2.1 、 borrowSyncRecordVo --->序列化 json
        String reqData = JSON.toJSONString(borrowSyncRecordVo);
        log.info("ReqData ---->{}:",reqData);
        //2.2 、编码
        reqData = EncryptUtil.encodeUTF8StringBase64(reqData);
        reqData = EncryptUtil.encodeURL(reqData);

        //2.3 、发送请求
        String url = "http://localhost:5600/service?serviceName=SYNC_BORROW_RECORD&reqData="+reqData ;
        String message = restTemplate.getForObject(url, String.class);
        log.info("接收银行托管中心的返回数据时:{}",message);

        //3 ，修改交易记录的同步状态
        if (message != null) {
            tradeLog.setSynchronizeStatus(1);
            tradeLog.setConfirmDate(new Date());

            tradeLogMapper.updateByPrimaryKey(tradeLog);
        }else {
            throw new BusinessException(BusinessCode.BORROW_SYNC_ERROR);
        }
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        String info = "蜗牛学院" ;
        info = URLEncoder.encode(info,"UTF-8");
        System.out.println(info);
        info = URLDecoder.decode(info,"UTF-8");
        System.out.println(info);

        List<Integer> integers = Arrays.asList(2, 3, 4, 5, 6, 67);

        Object[] objects = integers.toArray();
    }
}
